#ifndef __MY_GL_MAZE__
#define __MY_GL_MAZE__

#include "StdAfx.h"
#include "Defines_MazeSpecific.h"
#include "Cell.h"
#include "TypeDefs.h"

enum Direction {up, down, left, right};
enum LineType  {lHor, lVert, l9_12, l3_12, l3_6, l6_9};

//Crosroad in the Maze, should be used for routing
class CCrosRoad
{
	int m_col;//crossroard position
	int m_row;//crossroard position

	CellPosition m_possible_cells[4];//list of cells available to step to from this crossroad
	int          m_num_valid_cells;//num of cells available

	int m_last_used_cell;

public :
	CCrosRoad();
	~CCrosRoad();

	int GetCol()                     { return m_col; };
	int GetRow()                     { return m_row; };
	int GetNumValidCells()           { return m_num_valid_cells; };

	void SetRow(int row)   { m_row = row; };
	void SetCol(int col)   { m_col = col; };

	CellPosition *AddCell(int col, int row, int origin_col, int origin_row);
	CellPosition *FindCell(int col, int row);
	CellPosition *GetFirstNotUsedCell();
	CellPosition *GetLastUsedCell()  
	{ 
		if(m_last_used_cell >= 0)
			return &m_possible_cells[m_last_used_cell]; 
		else
			return NULL;
	};
};

//Maze
class CMaze
{
protected :
	bool m_valid;
	bool m_created;
	bool m_route_found;

	int  m_num_rows, m_num_columns;

	CMazeCell *m_cells[MAZE_Y_SIZE][MAZE_X_SIZE];

	CellPosContainer  m_cells_stack;
	CrosRoadContainer m_cros_stack;

	float m_x_cell_size; 
	float m_y_cell_size;

	int m_start_cell_x;
	int m_start_cell_y;

	int m_finish_cell_x;
	int m_finish_cell_y;

protected :

	int  Random(int max);
	
	//functions for creation of the Maze
	bool CellIsClosed(int x, int y);
	int  AnalizeNeighbours(int cur_x,  int cur_y,  CellPosition *neighbours);
	void EatAppropriateWall(int cur_x, int cur_y, int dest_x, int dest_y);

	void CleanCellsStack();
	void AddCellToStack(CellPosition *cell_pos);
	void RemoveCellFromStack(int row, int col);

	//functions for routing
	void CleanCrosStack();
	void AddCrosRoadToStack(CCrosRoad *cros);
	void RemoveCrosRoadFromStack(int row, int col);

	int  GetCellsToGoTo(int cur_x,  int cur_y, 
		                int prev_x, int prev_y, CellPosition *cells_to_go);

	Direction GetDirection(int cur_x, int cur_y, int prev_x, int prev_y);
	LineType  GetLineType(Direction d1, Direction d2);

public :
	CMaze(int num_rows, int num_columns);
	~CMaze();

	bool Valid()      { return m_valid;       };
	bool Created()    { return m_created;     };
	bool RouteFound() { return m_route_found; };

	void Draw();

	void FormMaze();

	bool TraceRoute();

	void DrawRoute();

	void SaveMazeToFile(char *fname);
};

#endif